﻿
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Remoting.Channels;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using Mysoft.Utility;
using 检查页面开放.Models;
using 检查页面开放.Utility;

namespace 检查页面开放.Business.Gnb
{
    /// <summary>
    /// 获取功能包中的多语言、没有写的多语言
    /// </summary>
    public class GetGnbLang
    {
        /// <summary>
        /// 功能包使用到的多语言
        /// </summary>
        private List<string> usedLangs = new List<string>();
        GitHelper giteHelper = new GitHelper();
        /// <summary>
        /// 功能包中已经定义的多语言
        /// </summary>
        private List<StringKey> alreadyLangs = new List<StringKey>();

        /// <summary>
        /// 入口
        /// </summary>
        /// <returns></returns>
        public List<string> GetLangList(string gitPath, string feature, bool isBldm)
        {
            //获取代码
            giteHelper.Clone(gitPath, feature, FeatureTypeEnum.Feature);
            //获取元数据
            string path = giteHelper.GetSrcPath();
            GetLange(path);
            usedLangs = usedLangs.Distinct().ToList();

            //异步删除代码
            if (isBldm == false)
            {
                new Task(() =>
                {
                    Thread.Sleep(2000);
                    PathHelper.DeletePath(path);
                }).Start();
            }
            else
            {
                //这里做特定处理，如果是财务接口独立：添加前缀，替换key
                if (gitPath.IndexOf("slxt_cwjk.git") > -1)
                {
                    LoadAllFile(path);
                    foreach (var lang in usedLangs)
                    {
                        ReplaceKeyForCwjk(lang);
                    }

                    foreach (var dic in replaceDictionary.Where(t => t.IsChge == true))
                    {
                        FileHelper.WriteFile(dic.Key, dic.Value);
                    }
                }
            }
            return GetNoDefineKey();
        }

        /// <summary>
        /// 获取已有的多语言
        /// </summary>
        /// <param name="fileInfo"></param>
        private void GetAlreadyLang(FileInfo fileInfo)
        {
            var text = System.IO.File.ReadAllText(fileInfo.FullName, Encoding.Default);
            LangModel functionModel = XmlUtility.DeserializeToObject<LangModel>(text);
            if (functionModel.Language == "zh-CHS")
            {
                alreadyLangs = functionModel.List.StringKeyList.ToList();
            }
        }
        /// <summary>
        /// 获取功能包中未定义的key
        /// </summary>
        /// <returns></returns>
        private List<string> GetNoDefineKey()
        {
            usedLangs = usedLangs.Distinct().ToList();
            List<string> noDeFines = new List<string>();
            foreach (var used in usedLangs)
            {
                var alreadyLang = alreadyLangs.FirstOrDefault(t => t.Key == used);
                if (alreadyLang == null)
                {
                    noDeFines.Add(used);
                }
            }
            return noDeFines;
        }

        private void GetLange(string path)
        {
            var dir = new DirectoryInfo(path);
            ILangeSearch search = null;
            foreach (var fileInfo in dir.GetFiles())
            {
                //多语言文件不用处理
                if (fileInfo.Directory.FullName.EndsWith(@"_metadata\Langs") == true)
                {
                    GetAlreadyLang(fileInfo);
                    continue;
                }
                switch (fileInfo.Extension)
                {
                    case ".js":
                        //如果是多语言设置
                        if (fileInfo.Name.EndsWith("LangRes.js"))
                        {
                            usedLangs.AddRange(LangJsDo(fileInfo));
                        }
                        else
                        {
                            search = new JsSearch();
                        }
                        break;
                    case ".cs":
                        if (fileInfo.Name.EndsWith("enum.cs", StringComparison.OrdinalIgnoreCase))
                        {
                            search = new EnumSearch();
                        }
                        else
                        {
                            search = new CsSearch();
                        }
                        break;
                    default:
                        if (fileInfo.Name.EndsWith(".metadata.config", StringComparison.OrdinalIgnoreCase))
                        {
                            search = new JsSearch();
                        }
                        break;
                }

                if (search != null)
                {
                    usedLangs.AddRange(search.Search(fileInfo));
                }
            }

            foreach (var fileInfo in dir.GetDirectories())
            {
                GetLange(fileInfo.FullName);
            }
        }

        /// <summary>
        /// 多语言js处理
        /// </summary>
        /// <param name="fileInfo"></param>
        /// <returns></returns>
        private List<string> LangJsDo(FileInfo fileInfo)
        {
            StringBuilder textSb = new StringBuilder();
            List<string> langKey = new List<string>();
            //循环js、查找js中的多语言:{##[lang:PriceMng_BtmMng_000001]##}
            foreach (string str in System.IO.File.ReadAllLines(fileInfo.FullName, Encoding.Default))
            {
                Regex regex = new Regex(@"(.*{##\[lang:).*(\]##})");
                Match match = regex.Match(str);
                if (string.IsNullOrEmpty(match.Groups[0].ToString()) == true)
                {
                    textSb.Append(str + "\r\n");
                    continue;
                }

                var jsUseName = str.Split(new string[] { ":" }, StringSplitOptions.None).FirstOrDefault();
                if (jsUseName == null)
                {
                    textSb.Append(str + "\r\n");
                    continue;
                }
                jsUseName = jsUseName.Trim();
                //检查是否被使用
                var isUsed = CheckLangJsIsUsed(jsUseName, giteHelper.GetSrcPath());
                if (isUsed == true)
                {
                    var value = match.Groups[0].ToString();
                    if (string.IsNullOrEmpty(value) == true)
                    {
                        break;
                    }
                    var re = value.Split(new string[] { @"##[lang:" }, StringSplitOptions.None).Last().Replace(@"]##}", "");
                    langKey.Add(re.Trim());
                    textSb.Append(str + "\r\n");
                }
            }
            //修改文件
            FileHelper.WriteFile(fileInfo.FullName, textSb.ToString());
            return langKey;
        }

        /// <summary>
        /// 检查多语言中名称的文字是否被使用
        /// </summary>
        /// <param name="usedName"></param>
        /// <param name="path"></param>
        /// <returns></returns>
        private bool CheckLangJsIsUsed(string usedName, string path)
        {
            var dir = new DirectoryInfo(path);
            var isUsed = false;
            foreach (var fileInfo in dir.GetFiles())
            {
                switch (fileInfo.Extension)
                {
                    case ".js":
                        //如果是多语言文件，跳过
                        if (fileInfo.Name.EndsWith("LangRes.js"))
                        {
                            break;
                        }
                        else
                        {
                            foreach (string str in System.IO.File.ReadAllLines(fileInfo.FullName, Encoding.Default))
                            {
                                if (str.IndexOf(usedName) > -1)
                                {
                                    isUsed = true;
                                    break;
                                }
                            }
                        }
                        break;
                }

                if (isUsed == true)
                {
                    break;
                }
            }

            if (isUsed == true)
            {
                return true;
            }

            foreach (var fileInfo in dir.GetDirectories())
            {
                isUsed = CheckLangJsIsUsed(usedName, fileInfo.FullName);
                if (isUsed == true)
                {
                    break;
                }
            }

            return isUsed;
        }

        private List<ListDic> replaceDictionary = new List<ListDic>();
        private List<string> CwjkMdels = new List<string> { "L0011_00110851", "L0011_00110852", "L0011_00110853" };
        private void ReplaceKeyForCwjk(string langKey)
        {
            if (CwjkMdels.Any(t => langKey.IndexOf(t) > -1))
            {
                return;
            }
            var replaceKey = "Cwjk_" + langKey;
            foreach (var dic in replaceDictionary)
            {
                var text = dic.Value;
                if (text.IndexOf(langKey) > -1)
                {
                    var oldKey = "[lang:" + langKey + "]";
                    var newKey = "[lang:" + replaceKey + "]";
                    if (dic.Key.EndsWith(".cs"))
                    {
                        oldKey = "\"" + langKey + "\"";
                        newKey = "\"" + replaceKey + "\"";
                    }
                    //循环js、查找js中的多语言:{##[lang:PriceMng_BtmMng_000001]##}
                    //后台2："L0011_00110851_PzExportErro".Translate();  枚举：""
                    text = text.Replace(oldKey, newKey);
                    dic.IsChge = true;
                }
                dic.Value = text;
            }
        }

        List<string> LoadFileType = new List<string>()
        {
            ".cs",".js",".config"
        };
        /// <summary>
        /// 加载所有文件
        /// </summary>
        /// <param name="path"></param>
        /// <param name="langKey"></param>
        private void LoadAllFile(string path)
        {
            var dir = new DirectoryInfo(path);
            foreach (var fileInfo in dir.GetFiles())
            {
                if (LoadFileType.Any(t => t == fileInfo.Extension.ToLower()))
                {
                    var encoding = EncodingType.GetEncoding(fileInfo.FullName);
                    replaceDictionary.Add(new ListDic
                    {
                        Key = fileInfo.FullName,
                        Value = System.IO.File.ReadAllText(fileInfo.FullName, encoding)
                    });
                }
            }

            foreach (var fileInfo in dir.GetDirectories())
            {
                LoadAllFile(fileInfo.FullName);
            }
        }
    }

    internal interface ILangeSearch
    {
        List<string> Search(FileInfo fileInfo);
    }

    internal class JsSearch : ILangeSearch
    {
        public List<string> Search(FileInfo fileInfo)
        {
            List<string> langKey = new List<string>();
            //循环js、查找js中的多语言:{##[lang:PriceMng_BtmMng_000001]##}
            foreach (string str in System.IO.File.ReadAllLines(fileInfo.FullName, Encoding.Default))
            {
                Regex regex = new Regex(@"(.*{##\[lang:).*(\]##})");
                Match match = regex.Match(str);
                if (string.IsNullOrEmpty(match.Groups[0].ToString()) == true)
                {
                    continue;
                }
                var value = match.Groups[0].ToString();
                if (string.IsNullOrEmpty(value) == true)
                {
                    break;
                }

                var re = value.Split(new string[] { @"##[lang:" }, StringSplitOptions.None).Last().Replace(@"]##}", "");
                langKey.Add(re.Trim());
            }

            return langKey;
        }
    }

    internal class EnumSearch : ILangeSearch
    {
        public List<string> Search(FileInfo fileInfo)
        {
            List<string> langKey = new List<string>();
            //枚举: [MultiLanguage("L0011_000329")]
            foreach (string str in System.IO.File.ReadAllLines(fileInfo.FullName, Encoding.Default))
            {
                Regex regex = new Regex(@"(.*\[MultiLanguage\().*(\)\])");
                Match match = regex.Match(str);
                if (string.IsNullOrEmpty(match.Groups[0].ToString()) == true)
                {
                    continue;
                }
                var value = match.Groups[0].ToString();
                if (string.IsNullOrEmpty(value) == true)
                {
                    break;
                }

                var re = value.Split(new string[] { "MultiLanguage(\"" }, StringSplitOptions.None).Last().Replace("\")]", "");
                langKey.Add(re.Trim());
            }

            return langKey;
        }
    }

    internal class CsSearch : ILangeSearch
    {
        public List<string> Search(FileInfo fileInfo)
        {
            List<string> langKey = new List<string>();
            //后台1：public static string L001100110851PzExportErro => "L0011_00110851_PzExportErro".Translate();
            //后台2："L0011_00110851_PzExportErro".Translate(); 
            foreach (string str in System.IO.File.ReadAllLines(fileInfo.FullName, Encoding.Default))
            {
                Regex regex = new Regex("(\").*(\\.Translate\\(\\))");
                Match match = regex.Match(str);
                if (string.IsNullOrEmpty(match.Groups[0].ToString()) == true)
                {
                    continue;
                }
                var value = match.Groups[0].ToString();
                if (string.IsNullOrEmpty(value) == true)
                {
                    break;
                }

                var re = value.Split(new string[] { ".Translate()" }, StringSplitOptions.None).First().Replace("\"", "");
                langKey.Add(re.Trim());
            }

            return langKey;
        }
    }
}